package ar.com.photo_admin.domain

import org.springframework.dao.DataIntegrityViolationException
import grails.plugins.springsecurity.Secured

@Secured(["isAuthenticated()"])
class PurchaseOrderController {

    static allowedMethods = [save: "POST", update: "POST", delete: "POST"]

	def purchaseOrderService
	def payingService
	def exportService
	def notificationsService
	def shoppingCartService
	
    def index() {
        redirect(action: "ordersMade", params: params)
    }

	def ordersRecieved(){
		params.max = Math.min(params.max ? params.int('max') : 10, 100)
		
		def orders = purchaseOrderService.listAllOrdersRecieved(params);
		
		if(params?.format && params.format != "html"){
			exportList(orders);
		}
				
		render(view: "list", model: [purchaseOrderInstanceList: orders, total: purchaseOrderService.listAllOrdersRecieved().size()])
	}
	
	def ordersMade(){
		params.max = Math.min(params.max ? params.int('max') : 10, 100)
		
		def orders = purchaseOrderService.listAllOrdersMade(params);
		
		if(params?.format && params.format != "html"){
			exportList(orders);
		}
				
		render(view: "list", model: [purchaseOrderInstanceList: orders, total: purchaseOrderService.listAllOrdersMade().size()])
	}
	
	def exportList(orders){
		// Exportacion de la lista de pedidos
		
		response.contentType = grailsApplication.config.grails.mime.types[params.format]
		response.setHeader("Content-disposition", "attachment; filename=pedidos.${params.extension}")
		
		
		List fields = ["dateCreated","photographer", "client","amountCopies","price"]
		Map labels = ["dateCreated": "Fecha pedido", "photographer": "Fotografo","client": "Cliente", "amountCopies":"Copias","price":"Precio"]
		
		// Formatter closure
		def dateFormat = { domain, value ->
			return value.format('dd-MM-yyyy')
		}
		
		Map formatters = [dateCreated:dateFormat]
		Map parameters = [title: "Pedidos", "column.widths": [0.2, 0.2, 0.2, 0.2,0.2]]
				
		exportService.export(params.format, response.outputStream,orders, fields, labels, formatters, parameters)
		
	}

    def create() {
        [purchaseOrderInstance: new PurchaseOrder(params)]
    }

    def save() {
        def purchaseOrderInstance = new PurchaseOrder(params)
        if (!purchaseOrderInstance.save(flush: true)) {
            render(view: "create", model: [purchaseOrderInstance: purchaseOrderInstance])
            return
        }

		flash.message = message(code: 'default.created.message', args: [message(code: 'purchaseOrder.label', default: 'PurchaseOrder'), purchaseOrderInstance.id])
        redirect(action: "show", id: purchaseOrderInstance.id)
    }

    def show() {
		log.info "PID "+params.id
        def purchaseOrderInstance = PurchaseOrder.get(params.id)
		def purchaseOrderItemsList = PurchaseOrderItem.findAllByPurchaseOrder(purchaseOrderInstance, params);
		
		// Exportacion de un pedido en particular			
		if(params?.format && params.format != "html"){			
			response.contentType = grailsApplication.config.grails.mime.types[params.format]
			response.setHeader("Content-disposition", "attachment; filename=pedido${purchaseOrderInstance.id}.${params.extension}")
			purchaseOrderService.exportOrder(purchaseOrderInstance,params?.format,response.outputStream)
			
		}					
		
        if (!purchaseOrderInstance) {
			flash.message = message(code: 'default.not.found.message', args: [message(code: 'purchaseOrder.label', default: 'PurchaseOrder'), params.id])
            redirect(action: "list")
            return
        }

        [purchaseOrderInstance: purchaseOrderInstance, purchaseOrderItemsList:purchaseOrderItemsList];
    }

    def edit() {
        def purchaseOrderInstance = PurchaseOrder.get(params.id)
        if (!purchaseOrderInstance) {
            flash.message = message(code: 'default.not.found.message', args: [message(code: 'purchaseOrder.label', default: 'PurchaseOrder'), params.id])
            redirect(action: "list")
            return
        }

        [purchaseOrderInstance: purchaseOrderInstance]
    }

 

    def deleteOrder() {
        def purchaseOrderInstance = PurchaseOrder.get(params.orderId)
		if (!purchaseOrderInstance.confirmed){
			flash.message = message(code: 'order.delete')
			purchaseOrderService.deletePurchaseOrder(purchaseOrderInstance);
		}
		redirect(controller:"index")
    }
	
	// El usuario solo desea encargar la orden de compra.
	def completeConfirmation(){
		def purchaseOrderInstance = PurchaseOrder.get(params.orderId)
		purchaseOrderService.completeConfirmation(purchaseOrderInstance)
		shoppingCartService.emptyShoppingCart(purchaseOrderInstance.photographer.id)
		flash.message = message(code: 'cart.register')
		redirect(action: "show", id: purchaseOrderInstance.id)
	}
	
	// Luego de elegir las fotos, el usuario pasa a la pantalla donde ve los datos generales de la compra
	// y decide si la compra por MP o solamente la encarga.
	def confirmOrder(){
		PurchaseOrder purchaseOrderInstance = PurchaseOrder.get(new Long(params.id))									
		
		Photographer photographer = purchaseOrderInstance.photographer 
		def checkoutUrl = photographer.paymentOnlineEnabled ? payingService.createPreference(purchaseOrderInstance,photographer.clientId,photographer.clientSecret) : "";
				
		[purchaseOrderInstance: purchaseOrderInstance,checkoutUrl: checkoutUrl];
	}
	
	
	def cancelOrder(){
		cancelOrRefundOrder(true)
	}
	
	
	def refundOrder(){		
		cancelOrRefundOrder(false)
	}
	
	def finishOrder(){		
		purchaseOrderService.finishOrder(params.id);
		flash.message = message(code: 'order.finalized.message')
		redirect(action: "show", id: params.id)
	}
	
	
	
	
	def cancelOrRefundOrder(cancel){
		log.info (cancel ? "Cancelando": "Devolviendo") + " orden id:" + params.id
		PurchaseOrder purchaseOrderInstance = PurchaseOrder.get(params.id)
		def successfulOp = false;
		

		if(purchaseOrderInstance.paidOnline){
			// Se analiza si se se trata de una orden pagada en mercado pago
			// La actualizacion del estado a cancelado o devuelto se realiza UNICAMENTE despues de la confirmacion
			// de MercadoPAGO.
			if (purchaseOrderInstance.MPpaymentId != null)
				successfulOp = payingService.cancelOrRefundOrder(purchaseOrderInstance.MPpaymentId,cancel,purchaseOrderInstance.photographer.clientId,purchaseOrderInstance.photographer.clientSecret)
				
			if(successfulOp){
				def successCode = cancel ? 'order.paidonline.cancelled.message' : 'order.paidonline.refunded.message';
				flash.message = message(code: successCode)
				redirect(action: "ordersRecieved")
			}
			else {
				def errorCode = cancel ? 'order.cancel.error' : 'order.refund.error';
				flash.message = message(code: errorCode)
				redirect(action: "show", id: purchaseOrderInstance.id)
			}
		}
		else {
			//Se trata de una orden de solo encargo.

			if (cancel)
				purchaseOrderInstance.cancel()
			else
				purchaseOrderInstance.refund()		
	
			notificationsService.notifyOrderStatusChange(purchaseOrderInstance);
			def successCode = cancel ? 'order.cancelled.message' : 'order.refunded.message';
			flash.message = message(code: successCode)
			redirect(action: "ordersRecieved")			
		}

		
				
	
				
	}
	
	
	
	
}
